package com.util;



import com.exception.CustomerException;

import java.sql.*;

/**
 * 数据库操作的基础工具类
 * Connection
 * PreparedStatement
 * ResultSet
 */
public class DBUtil {

    private static Connection connection = null;
    private static PreparedStatement preparedStatement = null;
    private static ResultSet resultSet = null;


    static {
        try {
            //通过反射加载驱动的区别, 在javaSE和javaEE的程序中体现完全不同
            Class.forName("com.mysql.jdbc.Driver");
        }catch (Exception e){
            e.printStackTrace();
            throw new CustomerException("注册驱动失败!");
        }
    }

    /**
     * 建立和数据库的连接
     * url/username/pwd 数据库连接使用的基础参数应该配置在配置文件中(db.properties)
     */
    public static Connection getConnection() {

        try {
            // http://www.baidu.com:80/index.html
            // 5.7 版本和8 区别: 8必须提供时区
            // GMT: 格林威治标准时区 , 用在表示中国时间的时候: GMT+8
            //  UTC: 统一标准时区
            String url = "jdbc:mysql://localhost:3306/cmsdb?";
            String username = "root";
            String pwd = "1234";
            connection = DriverManager.getConnection(url, username, pwd);

        }catch (Exception e){
            e.printStackTrace();
            throw new CustomerException("获取驱动失败!");
        }
        return connection;
    }

    /**
     * 创建预编译语句对象
     * @param sql 要执行的sql命令
     * @return 执行了预编译之后的命令对象(对象全局化, 此处是否返回都可以)
     */
    public static PreparedStatement createPreparedStatement(String sql) {
        try {
            preparedStatement = getConnection().prepareStatement(sql);
        }catch (Exception e){
            e.printStackTrace();
            throw new CustomerException("获取预编译的Statement失败");
        }
        return preparedStatement;
    }

    /**
     * 执行增删改的方法
     * @param preparedStatement 增删改类型的sql语句的执行命令对象
     * @return 影响的行数
     * @throws SQLException
     */
    public static int execUpdate(PreparedStatement preparedStatement) {
        try {
            return preparedStatement.executeUpdate();
        }catch (Exception e){
            e.printStackTrace();
            throw new CustomerException("执行sql失败!");
        }
    }

    /**
     * 执行查询的方法
     * @param preparedStatement 查询类型的sql语句的执行命令对象
     * @return 返回结果集
     * @throws SQLException
     */
    public static ResultSet execQuery(PreparedStatement preparedStatement)  {
        try {
            resultSet = preparedStatement.executeQuery();
        }catch (Exception e){
            e.printStackTrace();
            throw new CustomerException("结果集获取失败!");
        }
        return resultSet;
    }

    public static void close()  {

        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            resultSet=null;
        }

        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            preparedStatement=null;
        }

        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            connection=null;
        }
    }

}

